package org.iwidget.desktop.ui;
import org.iwidget.desktop.model.ElementTextArea;
import org.iwidget.desktop.model.WidgetElement;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
 *
 * @author Muhammad Hakim A
 */

public class WidgetTextArea extends JComponent
    implements MouseListener, MouseMotionListener, KeyListener, DropTargetListener, AdjustmentListener
{

    public WidgetTextArea(WidgetElement widget, ElementTextArea textData)
    {
        this.widget = widget;
        this.textData = textData;
        textData.setUIComponent(this);
        setBackground(new Color(0, 0, 0, 0));
        setOpaque(true);
        setSize(textData.getWidth(), textData.getHeight());
        setLocation(textData.getX(), textData.getY());
        setDoubleBuffered(true);
        setFocusable(true);
        textArea = new JTextArea();
        textArea.setSize(textData.getWidth(), textData.getHeight());
        scroller = new JScrollPane();
        scroller.setBackground(new Color(0, 0, 0, 0));
        scroller.setSize(textData.getWidth(), textData.getHeight());
        scroller.getViewport().add(textArea);
        scroller.getViewport().setBackground(new Color(0, 0, 0, 0));
        scroller.setAutoscrolls(true);
        scroller.getVerticalScrollBar().addAdjustmentListener(this);
        scroller.getHorizontalScrollBar().addAdjustmentListener(this);
        add(scroller);
        setScrollers();
        textArea.setDoubleBuffered(true);
        updateTextArea();
        textArea.addMouseListener(this);
        textArea.addMouseMotionListener(this);
        textArea.addKeyListener(this);
        setVisible(true);
    }

    public void setScrollers()
    {
        if(textData.getHScrollbar())
            scroller.setHorizontalScrollBarPolicy(30);
        else
            scroller.setHorizontalScrollBarPolicy(31);
        if(textData.getVScrollbar())
            scroller.setVerticalScrollBarPolicy(20);
        else
            scroller.setVerticalScrollBarPolicy(21);
    }

    public String getText()
    {
        return textArea.getText();
    }

    public void setEditable(boolean b)
    {
        textArea.setEditable(b);
    }

    public void updateText()
    {
        textArea.setText(textData.getDataInternal());
        repaint();
    }

    public void updateSize()
    {
        setSize(textData.getWidth(), textData.getHeight());
        scroller.setSize(textData.getWidth(), textData.getHeight());
        textArea.setSize(textData.getWidth(), textData.getHeight());
    }

    public Color getColorObject()
    {
        if(textData.getColor().startsWith("#") && textData.getColor().length() == 7)
        {
            int intColor = Integer.decode(textData.getColor()).intValue();
            Color c = new Color(intColor, true);
            if(textData.widget != null)
            {
                float masterOpacity = (float)textData.widget.getWindowJS().getOpacity() / 100F;
                masterOpacity *= (float)textData.getOpacity() / 100F;
                return new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(255F * masterOpacity));
            } else
            {
                return new Color(c.getRed(), c.getGreen(), c.getBlue());
            }
        } else
        {
            return Color.BLACK;
        }
    }

    public Color getBGColorObject()
    {
        if(textData.getBgColor().startsWith("#") && textData.getBgColor().length() == 7)
        {
            int intColor = Integer.decode(textData.getBgColor()).intValue();
            Color c = new Color(intColor, true);
            if(textData.widget != null)
            {
                float masterOpacity = (float)textData.widget.getWindowJS().getOpacity() / 100F;
                masterOpacity *= (float)textData.getBgOpacity() / 100F;
                return new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(255F * masterOpacity));
            } else
            {
                return new Color(c.getRed(), c.getGreen(), c.getBlue());
            }
        } else
        {
            return Color.WHITE;
        }
    }

    public void updateTextArea()
    {
        textArea.setForeground(getColorObject());
        textArea.setBackground(getBGColorObject());
        textArea.setFont(textData.getFontObject());
        if(textData.getCursorObject() != null)
            textArea.setCursor(textData.getCursorObject());
        if(textData.getTooltip() != null && textData.getTooltip().length() > 0)
            textArea.setToolTipText(textData.getTooltip());
    }

    public void initializeDrop()
    {
    }

    public void paint(Graphics g)
    {
        updateTextArea();
        if(textData.getVisible() && textData.getOpacity() > 0)
            super.paint(g);
        if(widget != null && widget.getUIComponent() != null)
            widget.getUIComponent().repaint();
    }

    public void adjustmentValueChanged(AdjustmentEvent e)
    {
        if(widget != null && widget.getUIComponent() != null)
            widget.getUIComponent().repaint();
    }

    public void mousePressed(MouseEvent e)
    {
        if(e.getButton() != 3)
            textData.triggerEvent("onMouseDown");
    }

    public void mouseReleased(MouseEvent e)
    {
        if(e.getButton() != 3)
            textData.triggerEvent("onMouseUp");
        else
            widget.getUIComponent().showContextMenu();
    }

    public void mouseEntered(MouseEvent e)
    {
        if(widget.getAction("onKeyDown") != null || widget.getAction("onKeyUp") != null || widget.getAction("onKeyPress") != null)
            textArea.grabFocus();
        textData.triggerEvent("onMouseEnter");
    }

    public void mouseExited(MouseEvent e)
    {
        textData.triggerEvent("onMouseExit");
    }

    public void mouseMoved(MouseEvent mouseevent)
    {
    }

    public void mouseClicked(MouseEvent mouseevent)
    {
    }

    public void mouseDragged(MouseEvent e)
    {
        widget.getUIComponent().mouseDragged(e);
    }

    public void keyTyped(KeyEvent e)
    {
        textData.triggerEvent("onKeyPress");
    }

    public void keyPressed(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        textData.triggerEvent("onKeyDown");
    }

    public void keyReleased(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        textData.triggerEvent("onKeyUp");
        if(widget != null && widget.getUIComponent() != null)
            widget.getUIComponent().repaint();
    }

    public void dragOver(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dropActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragEnter(DropTargetDragEvent e)
    {
        System.out.println("DragEnter");
        textData.triggerEvent("onDragEnter");
    }

    public void dragExit(DropTargetEvent e)
    {
        System.out.println("DragExit");
        textData.triggerEvent("onDragExit");
    }

    public void drop(DropTargetDropEvent e)
    {
        System.out.println("DragDrop");
        try
        {
            Transferable tr = e.getTransferable();
            if(tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
            {
                e.acceptDrop(3);
                ArrayList dropFiles = new ArrayList();
                ArrayList dropDirs = new ArrayList();
                java.util.List fileList = (java.util.List)tr.getTransferData(DataFlavor.javaFileListFlavor);
                for(Iterator iterator = fileList.iterator(); iterator.hasNext();)
                {
                    File file = (File)iterator.next();
                    if(file.isDirectory())
                        dropDirs.add(file.getAbsolutePath());
                    else
                        dropFiles.add(file.getAbsolutePath());
                }

                e.getDropTargetContext().dropComplete(true);
                String dropFilesArray[] = new String[dropFiles.size()];
                for(int iCtr = 0; iCtr < dropFiles.size(); iCtr++)
                    dropFilesArray[iCtr] = (String)dropFiles.get(iCtr);

                widget.getIwidgetData().droppedObjects = dropFilesArray;
                widget.getIwidgetData().droppedObjectsType = "filenames";
                textData.triggerEvent("onDragDrop");
            } else
            if(tr.isDataFlavorSupported(DataFlavor.stringFlavor))
            {
                e.acceptDrop(3);
                String url = (String)tr.getTransferData(DataFlavor.stringFlavor);
                if(url.toLowerCase().startsWith("http:") || url.toLowerCase().startsWith("https:") || url.toLowerCase().startsWith("ftp:"))
                {
                    String dropUrl[] = {
                        url
                    };
                    widget.getIwidgetData().droppedObjects = dropUrl;
                    widget.getIwidgetData().droppedObjectsType = "url";
                    e.getDropTargetContext().dropComplete(true);
                    textData.triggerEvent("onDragDrop");
                } else
                {
                    e.rejectDrop();
                }
            } else
            {
                System.err.println("Rejected");
                e.rejectDrop();
            }
        }
        catch(IOException io)
        {
            io.printStackTrace();
            e.rejectDrop();
        }
        catch(UnsupportedFlavorException ufe)
        {
            ufe.printStackTrace();
            e.rejectDrop();
        }
    }

    private static final long serialVersionUID = 0x2d34343638323339L;
    private WidgetElement widget;
    private ElementTextArea textData;
    private JTextArea textArea;
    private JScrollPane scroller;
    private Image myImage;
}